home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i029: Command-line editor with predictions, Part01/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Mark James <cpsc.UCalgary.CA!jamesm>
- Posting-number: Volume 20, Issue 29
- Archive-name: reactivekbd/part01
-
- [ This is one of the wildest concepts I've seen; not unlike DWIM in
- the Interlisp world, I guess. It uses pty's and BSD-style ioctl's.
- The package also has the FSF getopt(3) bundled in. /r$ ]
-
- The Reactive Keyboard is a general purpose command line editor with the
- addition of predictive text generation. It interfaces with a standard
- shell and allows simple editing of input lines. It will also predict new
- input lines based on previous input. Typing "make" will create the
- program in the current directory.
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 4)."
- # Contents: MANIFEST Makefile README command_line.c dt_complete.c
- # file+rk.h freq.c functions.h myabspath.c myabspath.h rk_button.c
- # rk_button.h rk_file.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(654 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1
- X Makefile 1
- X README 1
- X command_line.c 1
- X dt_complete.c 1
- X file+rk.c 3
- X file+rk.h 1
- X freq.c 1
- X functions.c 4
- X functions.h 1
- X getopt.c 2
- X myabspath.c 1
- X myabspath.h 1
- X parse_keys.c 2
- X rk.1 2
- X rk_button.c 1
- X rk_button.h 1
- X rk_file.c 1
- END_OF_FILE
- if test 654 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(314+ characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- XCFLAGS = -g
- X
- XOBJS = file+rk.o rk_file.o rk_button.o parse_keys.o getopt.o \
- X dt_complete.o functions.o myabspath.o command_line.o
- X
- X.c.o:
- X cc $(CFLAGS) -c $<
- X
- Xall: rk rk.man freq
- X
- Xrk: $(OBJS)
- X cc $(CFLAGS) -o rk $(OBJS) -ltermcap
- X
- Xrk.man : rk.1
- X tbl rk.1|nroff -man > rk.man
- X
- Xfreq: freq.c
- X cc $(CFLAGS) -o freq freq.c
- END_OF_FILE
- echo 'shar: Size check ignored; edited by moderator for long lines.'
- #if test 314 -ne `wc -c <'Makefile'`; then
- # echo shar: \"'Makefile'\" unpacked with wrong size!
- #fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(454 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThe Reactive Keyboard is a general purpose command line editor with the
- Xaddition of predictive text generation. It interfaces with a standard shell
- Xand allows simple editing of input lines. It will also predict new input
- Xlines based on previous input. Typing "make"
- Xwill create the program in the current directory.
- X
- XPermission is granted for any individual or institution to use, copy or
- Xdistribute this program so long as it is not sold for profit.
- END_OF_FILE
- if test 454 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'command_line.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'command_line.c'\"
- else
- echo shar: Extracting \"'command_line.c'\" \(5852 characters\)
- sed "s/^X//" >'command_line.c' <<'END_OF_FILE'
- X#define ZERO_FREQ_FILE "/.rk.zero_freq"
- X#define PRIME_FILE "/.rk.log_file"
- X#define KEY_FILE "/.rk.keys"
- X
- X#include "file+rk.h"
- X#include "rk_button.h"
- X#include "sys/file.h"
- X#include <stdio.h>
- X
- Xprint_help()
- X{
- X printf("RK command line arguments:\n");
- X
- X printf(" -b <buffers> The number of buffers used by rk to save previous\n");
- X printf(" commands used by 'previous_line'. Default: 60.\n\n");
- X
- X printf(" -e <length> The maximum length of predictions at the end of the\n");
- X printf(" line. Default: 40.\n\n");
- X
- X
- X printf(" -f <count> The maximum frequency count for any given context\n");
- X printf(" Default: 128\n\n");
- X
- X printf(" -i <length> The maximum length of predictions in the middle of\n");
- X printf(" the line. Default: 8.\n\n");
- X
- X printf(" -k <keys file> The file to read key bindings from.\n");
- X printf(" Default:$HOME/.rk.keys\n\n");
- X
- X printf(" -n <nodes> The amount of memory to allocate initially to speed\n");
- X printf(" up creation of nodes. After this memory is used up,\n");
- X printf(" more will be allocated, but this will be slower.\n");
- X printf(" Default: 64*1024 nodes.\n\n");
- X
- X printf(" -o <order> This argument controls how deep a tree will be built\n");
- X printf(" by rk inorder to make predictions. As order\n");
- X printf(" increases, the accuracy of predictions increases,\n");
- X printf(" but the speed decreases. Default: 8.\n\n");
- X printf(" -p <prime file> The file used to prime the Reactive Keyboard.\n");
- X printf(" Default:$HOME/.rk.log_file.\n\n");
- X
- X
- X printf(" -s <startup> The maximum number of characters to be read from the\n");
- X printf(" prime file at startup. Default: 16*1024.\n\n");
- X
- X printf(" -z <zero freq> The zero frequency file name.\n");
- X printf(" Default:$HOME/.rk.zero_freq\n\n");
- X
- X printf(" -A Toggle add_space_mode\n");
- X printf(" -E Toggle eol_only mode.\n");
- X printf(" -L Toggle eol_longer mode.\n");
- X printf(" -N Toggle truncate at newline mode.\n");
- X printf(" -P Toggle predictions on/off.\n");
- X printf(" -S Toggle show_eol_mode.\n");
- X printf(" -g Make this not a login shell.\n");
- X printf(" -h Print this help.\n");
- X printf(" -l Toggle lisp mode.\n");
- X printf(" -m Start up silently.\n");
- X printf(" -v Print Version.\n");
- X
- X}
- X
- Xprint_version()
- X{
- X char tbuf[128];
- X printf("RK_Button Version:%s.\n", RK_VERSION);
- X}
- X
- Xextern ED_STRUCT editor_data;
- X
- X
- Xget_command_line_arguments(argc,argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern int optind;
- X extern char *optarg;
- X int i;
- X
- X extern num_buffers;
- X extern char *zero_freq_file;
- X static char z_freq_buf[256];
- X extern char *prime_file;
- X static char prime_buf[256];
- X extern char *key_file;
- X static char key_buf[256];
- X extern max_len;
- X extern max_eol;
- X extern maxk;
- X extern maxprime;
- X extern max_freq;
- X extern max_nodes;
- X extern char silent;
- X extern char login;
- X extern char pred_mode,
- X pred_on_display,
- X lisp_mode,
- X nl_truncate_mode,
- X eol_only_mode,
- X eol_longer_mode,
- X add_space_mode,
- X show_eol_mode;
- X
- X zero_freq_file=prime_file=key_file=NULL;
- X
- X while ((i = getopt(argc, argv,"b:e:f:i:k:n:o:p:s:z:AELNPSghlmv"))
- X != EOF) {
- X switch( i ) {
- X case 'b': num_buffers=atoi(optarg)+1;
- X if(num_buffers<1)
- X abortit("-b:Buffers must be larger than 1.\n",-1);
- X break;
- X /* 1.. MAXINT*/
- X case 'e': max_eol=atoi(optarg);
- X if((max_eol<1)||(max_eol>132))
- X abortit("-e:End of line length must be between 1 and 132.\n",-1);
- X break;
- X /* 1..132 */
- X case 'f': max_freq=atoi(optarg);
- X if((max_freq<3)||(max_freq>255))
- X abortit("-f:Maximum Frequency must be between 3 and 255.\n",-1);
- X break;
- X case 'i': max_len=atoi(optarg);
- X if((max_len<1)||(max_len>132))
- X abortit("-i:Inline Length must be between 1 and 132.\n",-1);
- X break;
- X /* 1..132 */
- X case 'k':
- X if( key_file ) {
- X fprintf(stderr,"%s: Too many -k options\n",argv[0]);
- X abortit("",1);
- X }
- X key_file=optarg;
- X /* check for existance */
- X if(access(key_file,R_OK)){
- X perror(key_file);
- X abortit("",-1);
- X }
- X break;
- X case 'n': max_nodes=atoi(optarg);
- X if(max_nodes<0)
- X abortit("-n:Number of nodes must be positive.\n",-1);
- X break;
- X case 'o': maxk=atoi(optarg);
- X if((maxk<3)||(maxk>TOP_K)){
- X fprintf(stderr,"-o: Order must be between 3 and %d.\n",TOP_K);
- X abortit("",-1);
- X }
- X break;
- X case 'p':
- X if( prime_file ) {
- X fprintf(stderr, "%s: Too many -p options\n",argv[0]);
- X abortit("",1);
- X }
- X prime_file=optarg;
- X /* check for existance */
- X if(access(prime_file,(R_OK|W_OK))){
- X perror(prime_file);
- X abortit("",-1);
- X }
- X break;
- X case 's': maxprime=atoi(optarg); break;
- X
- X case 'z':
- X if( zero_freq_file ) {
- X fprintf(stderr, "%s: Too many -z options\n",argv[0]);
- X abortit("",1);
- X }
- X zero_freq_file=optarg;
- X /* check for existance */
- X if(access(zero_freq_file,(R_OK|W_OK))){
- X perror(zero_freq_file);
- X abortit("",-1);
- X }
- X break;
- X case 'A': add_space_mode=!add_space_mode; break;
- X case 'E': eol_only_mode=!eol_only_mode; break;
- X case 'L': eol_longer_mode=!eol_longer_mode; break;
- X case 'N': nl_truncate_mode=!nl_truncate_mode; break;
- X case 'P': pred_mode=!pred_mode; break;
- X case 'S': show_eol_mode=!show_eol_mode; break;
- X case 'g': login=!login; break;
- X case 'h': print_help(); abortit("",0); break;
- X case 'l': lisp_mode=!lisp_mode; break;
- X case 'm': silent=1; break;
- X case 'v': print_version();abortit("",0); break;
- X
- X
- X default:
- X fprintf(stderr,"\r%s: Use -h for help\r\n", argv[0]);
- X abortit("",-1);
- X }
- X
- X }
- X
- X if(zero_freq_file==NULL){
- X strcpy(z_freq_buf, getenv("HOME"));
- X strcat(z_freq_buf, ZERO_FREQ_FILE );
- X zero_freq_file=z_freq_buf;
- X }
- X if(prime_file==NULL){
- X strcpy(prime_buf, getenv("HOME"));
- X strcat(prime_buf, PRIME_FILE );
- X prime_file=prime_buf;
- X }
- X if(key_file==NULL){
- X strcpy(key_buf, getenv("HOME"));
- X strcat(key_buf, KEY_FILE );
- X key_file=key_buf;
- X }
- X
- X}
- END_OF_FILE
- if test 5852 -ne `wc -c <'command_line.c'`; then
- echo shar: \"'command_line.c'\" unpacked with wrong size!
- fi
- # end of 'command_line.c'
- fi
- if test -f 'dt_complete.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dt_complete.c'\"
- else
- echo shar: Extracting \"'dt_complete.c'\" \(13902 characters\)
- sed "s/^X//" >'dt_complete.c' <<'END_OF_FILE'
- X#include <alloca.h> /* JJD: some other alloc may be better to use */
- X#include <stdio.h>
- X#include <sys/file.h>
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#include <sys/stat.h>
- X#include <sys/param.h> /* JJD 3-89 added to get MAXPATHLEN and CANBSIZ*/
- X#include "file+rk.h"
- X#include "functions.h"
- X
- X
- X#define FILECOMPLETION 3 /* change if you need to change the binding of
- X filecompletion */
- X
- X/* MAX_FILENAME_LENGTH must be less than MAX_CMD_LINE_LENGTH (CANBSIZ, 256)*/
- X/* */
- X/* dir.h MAXNAMLEN is 255 (+1 for char []) JJD 3-89 #define */
- X
- X#define MAX_DIR_TO_SEARCH 16 /* WARNING: just a guess! */
- X#define MAX_FILES_TO_SAVE 1024 /* WARNING: just a guess! */
- X#define MAX_FILENAME_LENGTH MAXNAMLEN /* store bounds */
- X#define MAX_PATHNAME_LENGTH MAXPATHLEN
- X
- Xextern num_buffers;
- Xextern char *cursor_left;
- Xextern char output_string[];
- Xextern output_string_length;
- Xextern char pred_mode,pred_on_display;
- Xextern char pred_buff[];
- Xextern (*keymap[128][MAXEXTENSIONS]) ();
- X
- Xint run_ruptime (e) ED_STRUCT *e; {
- X
- X write (1, "\015\n", 2); /* JJD 3-89*/
- X quietly_run_program_connected_to_standard_tty ("uptime"); /* JJD 3-89*/
- X write (1, "Continue: ", 10);
- X draw_current_edit_line (e);
- X return OK;
- X}
- X
- X/* AN IDEA: a better way would look ahead a next char, if not this, put */
- X/* in the read buffer and return, else stay here - write (un)getc. */
- X
- Xint file_completion (e) ED_STRUCT *e; {
- X char *cwd,
- X *getcwd(),
- X *tdot,
- X *tchar,chr,
- X *f_name[MAX_FILES_TO_SAVE], /* JJD 3-89 to ptrs, defines*/
- X tstring[MAX_CMD_LINE_LENGTH + 1],
- X de_name[MAX_FILENAME_LENGTH + 1], /* JJD 3-89 dir entry name */
- X full_path[MAXPATHLEN];
- X
- X DIR *opendir(),
- X *dir_pointer;
- X
- X struct direct *readdir(),
- X *d_entry;
- X int match=0,
- X length,
- X past_first=0,
- X strncmp(),
- X ful_path=0,
- X count,
- X cmatch,
- X return_this = OK; /* JJD 2-89 added */
- X /* now look for start of filename to match */
- X for (tdot=e->dot;((*tdot != ' ') && (tdot != e->current_buffer));tdot--);
- X
- X /* if we aren't at the start of the whole buffer
- X then move ahead a char (to skip the space) */
- X if (tdot != e->current_buffer) tdot++;
- X /* and save the string to look for */
- X strcpy(tstring, tdot);
- X for (tchar=tstring;((*tchar != '\/')&&(*tchar!='\0'));tchar++);
- X if (*tchar == '\/') {
- X ful_path = 1;
- X strcpy(full_path,tstring);
- X tchar=full_path;
- X while (*tchar!='\0') tchar++;
- X while ((*tchar!='\/') && (tchar != full_path)) tchar--;
- X if (tchar != full_path) {
- X *tchar = '\0';
- X tchar++;strcpy(tstring,tchar);
- X }
- X }
- X if (ful_path){
- X cwd = full_path;
- X }
- X else {
- X void (*sig)();
- X sig=signal(SIGCHLD,SIG_DFL);
- X getcwd(full_path);cwd=full_path; /* get working directory */
- X signal(SIGCHLD,sig);
- X }
- X if ((dir_pointer = opendir(cwd)) == NULL){ /* and open it to look */
- X write(1, "\07",1);
- X return OK;
- X } /* now look for any matching filenames and
- X increment match if we find one */
- X d_entry=readdir(dir_pointer);
- X for (; d_entry != NULL; d_entry = readdir(dir_pointer)){
- X strcpy (de_name, d_entry->d_name);
- X if (strncmp(tstring, de_name, strlen(tstring)) == 0){
- X if ((strcmp(".", de_name) != 0) &&
- X (strcmp("..", de_name) != 0)){ /* JJD 3-89 del . .. */
- X f_name[match] = (char *) alloca (strlen(de_name) + 1);
- X strcpy(f_name[match],de_name);
- X if (++match >= MAX_FILES_TO_SAVE) {
- X goto tomany; /* JJD 3-89 forget about the rest of them */
- X }
- X }
- X }
- X }
- Xtomany:
- X if (match == 0) {
- X write(1,"\07",1);
- X if (dir_pointer != NULL) closedir(dir_pointer); /* JJD 3-89 added if*/
- X return OK;
- X }
- X /* else we found at least 1 match */
- X else {
- X ssort (f_name, match); /* JJD 3-89, alpha */
- X cmatch = 0;
- Xagain: output_string_length = 0;
- X if (!past_first) length=strlen(tstring);
- X else {
- X if (cmatch == 0) length=strlen(f_name[match-1]);
- X else length=strlen(f_name[cmatch-1]);
- X }
- X if (ful_path) length = length + strlen(full_path)+1;
- X /* so move the cursor to the beginning
- X of the file name */
- X for (; length; --length)
- X tputs (cursor_left, ONE_LINE,append_to_output_string);
- X /* set current dot to beginning of the
- X file name and copy in the filename*/
- X e->dot = tdot;
- X if (ful_path){
- X strcpy(e->dot,full_path);
- X strcat(e->dot,"\/");
- X strcat(e->dot,f_name[cmatch]);
- X }
- X
- X/* JJD: WARNING: prev and next str ops could overflow ed_buff, should test */
- X
- X else strcpy(e->dot,f_name[cmatch]);
- X /* reset dot to the end of the line */
- X if (e->mark > e->dot) e->mark += strlen (f_name[cmatch]);/*JJD 3-89*/
- X e->dot += strlen(f_name[cmatch]);
- X
- X/* JJD: WARNING: prev and next dot resets could overflow ed_buff, as above */
- X
- X if (ful_path) {
- X if (e->mark > e->dot) e->mark += strlen(full_path)+1;
- X e->dot += strlen(full_path)+1;
- X }
- X /* and concatenate onto output string the
- X filename, write it to screen */
- X if (ful_path) {
- X display_string_into_output_string(full_path);
- X display_string_into_output_string("\/");
- X }
- X display_string_into_output_string (f_name[cmatch]);
- X if (cmatch == 0)length=strlen(f_name[match-1])-strlen(f_name[cmatch]);
- X else length=strlen(f_name[cmatch-1])-strlen(f_name[cmatch]);
- X for (count=0;count<length;count++){
- X display_string_into_output_string(" ");
- X }
- X for (count=0;count<length;count++){
- X tputs (cursor_left, ONE_LINE,append_to_output_string);
- X }
- X write (1, output_string, output_string_length);
- X if (pred_mode) { /* JJD 2-89 added */
- X make_a_prediction (pred_buff);
- X if (pred_buff[0]) display_pred_buffer (e);
- X }
- X
- X READ(0,&chr,1);
- X chr &= 127; /* JJD 2-89 added */
- X if (pred_on_display) erase_pred_buffer (e); /* JJD 2-89 added */
- X if (chr == FILECOMPLETION) {
- X past_first = 1;
- X if (cmatch < match-1) {
- X cmatch++;
- X goto again;
- X }
- X else {cmatch=0;goto again;}
- X }
- X else {
- X/* JJD: it would be better to ungetc and return */
- X return_this = OK; /* JJD 2-89 added */
- X e->current_input_char = chr;
- X return_this = keymap[(int)chr][0](e); /* JJD 2-89 add return_this */
- X if (dir_pointer != NULL) closedir(dir_pointer); /* JJD 3-89 add if*/
- X return (return_this); /* JJD 2-89 add return_this */
- X }
- X }
- X }
- X
- X
- Xint command_completion (e) ED_STRUCT *e;{
- X char *path_var, /* points to the environment variable PATH */
- X *tdot,
- X *tchar,
- X chr,
- X *paths[MAX_DIR_TO_SEARCH], /* JJD 3-89 changed to ptrs */
- X *f_name[MAX_FILES_TO_SAVE],
- X tstring[MAX_CMD_LINE_LENGTH + 1],
- X d_name[MAX_PATHNAME_LENGTH + 1],
- X de_name[MAX_FILENAME_LENGTH + 1],
- X t_name[MAX_PATHNAME_LENGTH + MAX_FILENAME_LENGTH + 1],
- X *getenv();
- X int count,
- X num_dirs=0, /* number of directories to look in */
- X current_search_directory,/* the current directory to look at */
- X cmatch,
- X match=0,
- X length,
- X past_first=0,
- X return_this = OK; /* JJD 2-89 added */
- X
- XDIR *opendir(),
- X *dir_pointer;
- X
- Xstruct direct *readdir(),
- X *d_entry;
- Xstruct stat buf; /* JJD 3-89 added */
- X
- X /* get the file name to match */
- X for (tdot=e->dot;((*tdot != ' ') && (tdot != e->current_buffer));tdot--);
- X if (tdot != e->current_buffer) tdot++;
- X strcpy(tstring, tdot);
- X
- X path_var = getenv("PATH");
- X if (path_var == NULL) { /* JJD 3-89 added test */
- X write(1,"\07",1);
- X return OK;
- X }
- X else {
- X tchar = path_var; /* skip the first : */
- X/* JJD: this assumes a "normal" PATH, which it is 99.99% likely to be */
- X if (path_var[0] == ':') tchar++; /* JJD 3-89 added if */
- X while(*tchar != '\0'){
- X count=0; /* JJD 3-89 stay in bounds*/
- X while ((*tchar != ':') && (*tchar != '\0')) d_name[count++] = *tchar++;
- X if (*tchar == ':') tchar++;
- X d_name[count] = '\0';
- X paths[num_dirs] = (char *) alloca (strlen(d_name) + 1);
- X strcpy (paths[num_dirs], d_name);
- X if (++num_dirs >= MAX_DIR_TO_SEARCH) {
- X goto tomanydirs; /* JJD 3-89 forget the rest*/
- X }
- X }
- Xtomanydirs:
- X/* now have num_dirs directories to search for the command in */
- X/* JJD 3-89 NOW CHECKS FOR EXECUTE PERMISSION and NOT A DIRECTORY, */
- X/* THEN SORTS IN ALPHA ORDER, LEAVING IN DUPLICATED (are rare) */
- X
- X current_search_directory = 0; /* JJD 3-89 changed <= to < */
- X for (;current_search_directory<num_dirs;current_search_directory++){
- X strcpy (d_name, paths[current_search_directory]); strcat (d_name, "/");
- X if ((dir_pointer = opendir(&paths[current_search_directory][0])) != NULL){
- X d_entry=readdir(dir_pointer);
- X for (;d_entry != NULL;d_entry = readdir(dir_pointer)){
- X strcpy (de_name, d_entry->d_name);
- X if (strncmp(tstring, de_name, strlen(tstring)) == 0){
- X if ((strcmp(".", de_name) != 0) &&
- X (strcmp("..", de_name) != 0)) { /* JJD 3-89 del . .. */
- X strcpy (t_name, d_name); strcat (t_name, de_name);
- X if (access (t_name, X_OK) == 0) { /* executable */
- X if (stat(t_name,&buf) == 0){
- X if ((buf.st_mode & S_IFMT) != S_IFDIR){ /* not a dir */
- X f_name[match] = (char *) alloca (strlen(de_name) + 1);
- X strcpy(f_name[match],de_name);
- X if (++match >= MAX_FILES_TO_SAVE) {
- X goto tomanyfiles; /* JJD 3-89 above */
- X }
- X }
- X }
- X }
- X }
- X }
- X }
- X }
- Xtomanyfiles:
- X if (dir_pointer != NULL) closedir(dir_pointer);
- X }
- X if (match == 0) {
- X write(1,"\07",1);
- X return OK;
- X }
- X /* else we found at least 1 match */
- X else {
- X ssort (f_name, match); /* JJD 3-89, alpha */
- X cmatch = 0;
- Xagain: output_string_length = 0;
- X if (!past_first) length=strlen(tstring);
- X else {
- X if (cmatch == 0) length=strlen(f_name[match-1]);
- X else length=strlen(f_name[cmatch-1]);
- X }
- X for (; length; --length)
- X tputs (cursor_left, ONE_LINE,append_to_output_string);
- X/* set current dot to beginning of the file name and copy in the filename*/
- X e->dot = tdot;
- X strcpy(e->dot,f_name[cmatch]);
- X
- X/* JJD: WARNING: prev strcpy could overflow ed_buff, should test */
- X/* JJD: WARNING: next dot reset could overflow ed_buff, as above */
- X /* reset dot to the end of the line */
- X
- X if (e->mark > e->dot) e->mark += strlen (f_name[cmatch]); /* JJD 3-89 */
- X e->dot += strlen(f_name[cmatch]);
- X display_string_into_output_string (f_name[cmatch]);
- X if (cmatch == 0) length=strlen(f_name[match-1])-strlen(f_name[cmatch]);
- X else length=strlen(f_name[cmatch-1])-strlen(f_name[cmatch]);
- X for (count=0;count<length;count++){
- X display_string_into_output_string(" ");
- X }
- X for (count=0;count<length;count++){
- X tputs (cursor_left, ONE_LINE,append_to_output_string);
- X }
- X write (1, output_string, output_string_length);
- X if (pred_mode) { /* JJD 2-89 added */
- X make_a_prediction (pred_buff);
- X if (pred_buff[0]) display_pred_buffer (e);
- X }
- X
- X READ(0,&chr,1);
- X chr &= 127; /* JJD 2-89 added */
- X if (pred_on_display) erase_pred_buffer (e); /* JJD 2-89 added */
- X if (chr == (char)28) { /* JJD 2-89 made ^\*/
- X past_first = 1;
- X if (cmatch < match-1) {
- X cmatch++;
- X goto again;
- X }
- X else {cmatch=0;goto again;}
- X }
- X else {
- X/* JJD: it would be better to ungetc and return */
- X return_this = OK; /* JJD 2-89 added */
- X e->current_input_char = chr;
- X return_this = keymap[(int)chr][0](e); /* JJD 2-89 add return_this */
- X if (dir_pointer != NULL) closedir(dir_pointer); /* JJD 3-89 add if*/
- X return (return_this); /* JJD 2-89 add return_this */
- X }
- X }
- X }
- X}
- X
- X
- Xset_mark (e) ED_STRUCT *e; {
- X e->mark = e->dot; /* JJD 3-89 mark intialized in set_up_buffers()*/
- X e->current_ed_buff_ptr->mark = e->dot; /* JJD 3-89 added */
- X}
- X
- Xshow_mark (e) ED_STRUCT *e; {
- X int num_to_go;
- X if (e->mark > e->dot){
- X e->universal_argument = num_to_go = e->mark - e->dot;
- X forward_char (e);
- X sleep(1); /* JJD 3-89 change */
- X e->universal_argument = num_to_go;
- X backward_char (e);
- X }
- X else if (e->mark < e->dot){
- X e->universal_argument = num_to_go = e->dot - e->mark;
- X backward_char (e);
- X sleep(1); /* JJD 3-89 change */
- X e->universal_argument = num_to_go;
- X forward_char (e);
- X }
- X}
- X
- Xdelete_region_to_killbuffer (e) ED_STRUCT *e; {
- X
- X int length;
- X
- X if (e->dot > e->mark){
- X length = e->dot - e->mark;
- X strncpy(e->kill_buffer, e->mark, length);
- X e->kill_buffer[length] = '\0';
- X e->universal_argument = length;
- X backward_char(e);
- X e->universal_argument = length;
- X e->mark = e->dot;
- X return delete_char (e);
- X }
- X if (e->mark > e->dot){
- X length = e->mark - e->dot;
- X strncpy(e->kill_buffer, e->dot, length);
- X e->kill_buffer[length] = '\0';
- X e->universal_argument = length;
- X e->mark = e->dot;
- X return delete_char (e);
- X }
- X return OK; /* JJD 3-89 added */
- X}
- X
- X
- Xint strstr(look, lookin) char *look, *lookin;{
- X int counter = 0;
- X for (counter = 0; (counter < (strlen(lookin) - strlen(look))); counter++){
- X if (strncmp(look, &lookin[counter], strlen(look)) == 0)
- X return(0);
- X }
- X return(1);
- X}
- X
- X/*
- Xsend_message(message)
- Xchar *message;
- X{
- X ioctl (0, TIOCGETP, &new_stdin_sgttyb);
- X ioctl (0, TIOCSETP, &old_stdin_sgttyb);
- X printf ("recvd message:%s\n", message);
- X ioctl (0, TIOCSETP, &new_stdin_sgttyb);
- X}
- X*/
- X
- Xssort (v, n) char *v[]; int n; { /* JJD: Shell Sort alla p.108 K&R C book */
- X int gap, i, j; char *temp;
- X for (gap = n/2; gap > 0; gap /= 2)
- X for (i= gap; i < n; i++)
- X for (j = i-gap; j >= 0; j -= gap) {
- X if (strcmp(v[j], v[j+gap]) <= 0) break;
- X temp = v[j];
- X v[j] = v[j+gap];
- X v[j+gap] = temp;
- X }
- X}
- END_OF_FILE
- if test 13902 -ne `wc -c <'dt_complete.c'`; then
- echo shar: \"'dt_complete.c'\" unpacked with wrong size!
- fi
- # end of 'dt_complete.c'
- fi
- if test -f 'file+rk.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'file+rk.h'\"
- else
- echo shar: Extracting \"'file+rk.h'\" \(1071 characters\)
- sed "s/^X//" >'file+rk.h' <<'END_OF_FILE'
- X#include <sys/param.h> /* JJD 3-89 added to get MAXPATHLEN and CANBSIZ */
- Xchar *strcpy(), *strcat(); /* JJD 3-89 for lint */
- Xchar *gets(), *sprintf(), *malloc(); /* JJD 3-89 for lint */
- Xchar *sprintf(); /* JJD 3-89 for lint */
- Xchar *index();
- X
- X#define OK 0
- X#define FINISHED_EDITING -1
- X#define FINISHED_BUT_DONT_ADD_CTRL_M -2
- X#define HAVE_CHAR -3
- X#define UNIVERSAL_ARGUMENT_MAXIMUM 256
- X#define MAX_CMD_LINE_LENGTH CANBSIZ
- X#define VERSION "1.0 August 21st 1989"
- X#define RK_VERSION " 1.0 August 21st 1989"
- X#define ONE_LINE (int)1 /* JJD 3-89 was int dummy for tputs */
- X
- X
- Xstruct ed_buffs {
- X char string[MAX_CMD_LINE_LENGTH + 1];
- X char *dot;
- X char *mark; /* JJD 3-89 added */
- X struct ed_buffs *next_ptr;
- X struct ed_buffs *prev_ptr;
- X };
- X
- Xtypedef struct _ed_struct {
- X char current_input_char;
- X int universal_argument;
- X char *current_buffer;
- X char *dot;
- X char *mark;
- X char kill_buffer[MAX_CMD_LINE_LENGTH + 1];
- X struct ed_buffs *current_ed_buff_ptr;
- X } ED_STRUCT;
- X
- X#define MAXEXTENSIONS 12
- X
- END_OF_FILE
- if test 1071 -ne `wc -c <'file+rk.h'`; then
- echo shar: \"'file+rk.h'\" unpacked with wrong size!
- fi
- # end of 'file+rk.h'
- fi
- if test -f 'freq.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'freq.c'\"
- else
- echo shar: Extracting \"'freq.c'\" \(5223 characters\)
- sed "s/^X//" >'freq.c' <<'END_OF_FILE'
- X/* Written by John Darragh, Calgary Alberta, revised 3-89.
- X *
- X * freq.c: tabulates ASCII character frequencies from stdin and outputs
- X * freq sorted ASCII chars on the stdout in a number of formats.
- X *
- X * intended as a utility for rk_button to create its zero_freq
- X * startup FREQ_DATA_FILE and/or default zero_freq[] char array.
- X *
- X * this info is used by rk to predict chars it hasn't yet added
- X * to it's model (either by file priming or user command input).
- X *
- X * it puts any unseen chars in ASCII sequence, and puts any un-
- X * represented control codes (including DEL) at the end.
- X *
- X * defaults: outputs 256 chars as 128 ASCII char/NL pairs.
- X * (the NLs are just for readabilities sake, rk ignores them.)
- X *
- X * options:
- X * -c write output as a C array for inclusion in programs.
- X * -n don't put a NL after each of the 128 chars output.
- X * (intended for future revision to init_reactive() which
- X * would halve the freq file size from 256 -- saves space)
- X * <filename> read data from file other than stdin.
- X */
- X
- X#include <stdio.h>
- X
- X#define TRUE 1
- X#define FALSE 0
- X#define MAXTABLE 128 /* the size of the ASCII character set */
- X
- XFILE * infile = stdin; /* for <filename> arg */
- Xchar no_nls = FALSE; /* -n option above */
- Xchar c_array = FALSE; /* -c option above */
- Xint ch_table[MAXTABLE][2]; /* [][0] are labels, [][1] are freq counts */
- X
- Xmain (argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X char chr; register int i, j; int gap, temp[2];
- X
- X get_args (argc, argv); /* may change infile, no_nls, c_array */
- X /* init table labels and do the freq count */
- X for (i=0; i<MAXTABLE; i++) {
- X ch_table[i][0] = i; /* the ACSII code */
- X ch_table[i][1]= -(i+1); /* ensure ASCII order for 0-freqs */
- X } /* by intially -ve freq counts */
- X while ((chr = getc(infile)) != EOF) {
- X chr &= 0177;
- X if (ch_table[(int)chr][1] < 0) /* seen, so fix -ve freqs */
- X ch_table[(int)chr][1] = 0;
- X ch_table[(int)chr][1]++;
- X }
- X for (i=0; i<32; i++) {
- X if (ch_table[i][1] < 0) /* ensure 0-freq control codes */
- X ch_table[i][1] -= MAXTABLE; /* end up at the end */
- X }
- X if (ch_table[MAXTABLE-1][1] < 0) /* ensure same for DEL char */
- X ch_table[MAXTABLE-1][1] -= MAXTABLE;
- X /* frequency sort the thing (shell sort) */
- X for (gap = MAXTABLE/2; gap > 0; gap /= 2)
- X for (i= gap; i < MAXTABLE; i++)
- X for (j = i-gap; j >= 0; j -= gap) {
- X if (ch_table[j][1] <= ch_table[j+gap][1])
- X break;
- X temp[0] = ch_table[j][0];
- X temp[1] = ch_table[j][1];
- X ch_table[j][0] = ch_table[j+gap][0];
- X ch_table[j][1] = ch_table[j+gap][1];
- X ch_table[j+gap][0] = temp[0];
- X ch_table[j+gap][1] = temp[1];
- X }
- X /* output a compilable "C" character array */
- X if (c_array) {
- Xprintf ("static char zero_freq[128] = { /* by a user supplied $home/file */\n");
- X for (i=MAXTABLE-1; i>=0; i--) {
- X switch (chr = (char)(ch_table[i][0] & 127)) {
- X case '\n': printf (" \'\\n\',"); break;
- X case '\t': printf (" \'\\t\',"); break;
- X case '\b': printf (" \'\\b\',"); break;
- X case '\r': printf (" \'\\r\',"); break;
- X case '\f': printf (" \'\\f\',"); break;
- X case '\\': printf (" \'\\\\\',"); break;
- X case '\'': printf (" \'\\\'\',"); break;
- X case 127: printf ("\'\\%03o\',", (int)chr); break;
- X default: if (chr < 32) printf (" \'\\%02o\',", (int)chr);
- X else printf (" \'%1c\',", chr); break;
- X }
- X if (((i%8) == 0) && (i != 0)) printf ("\n");
- X }
- X printf ("};\n");
- X /* otherwise just put out sorted chars */
- X } else
- X for (i=MAXTABLE-1; i>=0; i--)
- X if (no_nls) printf ("%c", (char)ch_table[i][0]);
- X else printf ("%c\n", (char)ch_table[i][0]);
- X
- X abortit ("", 0);
- X}
- X
- X
- Xstatic char *options = " -n[no_nls] -c[c_array] <input file>\n";
- X
- Xstatic get_args (argc, argv) /* may change infile */
- Xint argc;
- Xchar **argv;
- X/*
- X * Get any command arguments and set any appropriate
- X * global flags and variables.
- X */
- X{
- X static char usage[256] = "usage: ";
- X
- X strcat (usage, &argv[0][0]); /* fill in name of object file */
- X strcat (usage, options);
- X
- X while ((argc > 1) && (argv[1][0] == '-')) {
- X switch (argv[1][1]) {
- X
- X case 'c': case 'C': /* turn on C char array output */
- X c_array = TRUE;
- X break;
- X
- X case 'n': case 'N': /* turn on "no NL" output mode */
- X no_nls = TRUE;
- X break;
- X
- X default: abortit (usage, -1);
- X
- X } /*switch*/
- X argc--; argv++;
- X
- X }
- X if (argc == 2) { /* file argument present */
- X if ((infile = fopen (&argv[1][0], "r")) == NULL) {
- X fprintf (stderr, "cannot open: %s\n", &argv[1][0]);
- X abortit (usage, -1);
- X }
- X } else if (argc != 1) abortit (usage, -1);
- X}/*get_args*/
- X
- X
- Xstatic abortit (message, status)
- Xchar *message;
- Xint status;
- X/*
- X * All program terminations are through this routine.
- X * It prints an optional message, then exits with
- X * the parameter status.
- X */
- X{
- X fprintf (stderr, "%s", message);
- X fflush (stderr);
- X exit (status);
- X}/*abortit*/
- END_OF_FILE
- if test 5223 -ne `wc -c <'freq.c'`; then
- echo shar: \"'freq.c'\" unpacked with wrong size!
- fi
- # end of 'freq.c'
- fi
- if test -f 'functions.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'functions.h'\"
- else
- echo shar: Extracting \"'functions.h'\" \(1578 characters\)
- sed "s/^X//" >'functions.h' <<'END_OF_FILE'
- Xint append_to_output_string();
- Xint accept_forward_char();
- Xint accept_forward_word();
- Xint accept_to_end_of_line();
- Xint backspace_char();
- Xint backspace_word();
- Xint backward_char();
- Xint backward_paren();
- Xint backward_word();
- Xint beginning_of_line();
- Xint BOGUS();
- Xint capitalize_word();
- Xint clear_display();
- Xint close_paren();
- Xint command_completion();
- Xint dash_to_ul_word();
- Xint delete_char();
- Xint delete_region_to_killbuffer();
- Xint delete_word();
- Xint describe_bindings();
- Xint describe_arguments();
- Xint discard_current_edit_line();
- Xint discard_rest_of_line();
- Xint end_of_line();
- Xint file_completion();
- Xint finish_editing_line();
- Xint forward_char();
- Xint forward_paren();
- Xint forward_word();
- Xint increment_universal_argument();
- Xint insert_interrupt_char();
- Xint insert_quit_char();
- Xint insert_start_char();
- Xint insert_stop_char();
- Xint insert_suspend_char();
- Xint lowercase_word();
- Xint meta_prefix();
- Xint next_line();
- Xint next_pred();
- Xint open_paren();
- Xint previous_line();
- Xint previous_pred();
- Xint prime_from_file();
- Xint quote_char();
- Xint run_mesg();
- Xint run_pp();
- Xint run_ruptime();
- Xint run_talk();
- Xint run_tty_program();
- Xint run_write();
- Xint self_insert();
- Xint set_mark();
- Xint show_free_nodes();
- Xint show_mark();
- Xint show_version();
- Xint toggle_add_space_mode();
- Xint toggle_show_eol_mode();
- Xint toggle_eol_longer_mode();
- Xint toggle_eol_only_mode();
- Xint toggle_lisp_mode();
- Xint toggle_nl_truncate_mode();
- Xint toggle_pred_mode();
- Xint twiddle_chars();
- Xint ul_to_dash_word();
- Xint uppercase_word();
- Xint yank_from_kill_buffer();
- END_OF_FILE
- if test 1578 -ne `wc -c <'functions.h'`; then
- echo shar: \"'functions.h'\" unpacked with wrong size!
- fi
- # end of 'functions.h'
- fi
- if test -f 'myabspath.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'myabspath.c'\"
- else
- echo shar: Extracting \"'myabspath.c'\" \(869 characters\)
- sed "s/^X//" >'myabspath.c' <<'END_OF_FILE'
- X/* Mark James 89/5/24*/
- X
- X
- X#include "myabspath.h"
- X#include <pwd.h>
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <strings.h>
- X
- X
- X/* returns 0 on success, NO_HOME if getenv("HOME") fails, NO_USER if ~user does not exist */
- X
- Xmyabspath(path,buff)
- Xchar *path;
- Xchar *buff;
- X{
- X char *homedir;
- X char *getenv();
- X char username[MAX_USER_NAME];
- X int i;
- X struct passwd *pwd;
- X
- X while (isspace(path[0])&&path[0])
- X path++;
- X if(path[0]=='~'){
- X path++;
- X if((path[0]=='/') || (path[0]==0)){
- X if((homedir=getenv("HOME"))==0)
- X return(NO_HOME);
- X strcpy(buff,homedir);
- X strcat(buff,path);
- X return(0);
- X }
- X else
- X {
- X for(i=0;(path[0]!='/')&&(path[0]!=0);i++,path++)
- X username[i]=path[0];
- X username[i]=0;
- X if((pwd=getpwnam(username))==0)
- X return(NO_USER);
- X strcpy(buff,pwd->pw_dir);
- X strcat(buff,path);
- X }
- X }
- X else
- X {
- X strcpy(buff,path);
- X return(0);
- X }
- X}
- X
- X
- X
- X
- END_OF_FILE
- if test 869 -ne `wc -c <'myabspath.c'`; then
- echo shar: \"'myabspath.c'\" unpacked with wrong size!
- fi
- # end of 'myabspath.c'
- fi
- if test -f 'myabspath.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'myabspath.h'\"
- else
- echo shar: Extracting \"'myabspath.h'\" \(64 characters\)
- sed "s/^X//" >'myabspath.h' <<'END_OF_FILE'
- X#define NO_HOME -1
- X#define NO_USER -2
- X
- X#define MAX_USER_NAME 40
- END_OF_FILE
- if test 64 -ne `wc -c <'myabspath.h'`; then
- echo shar: \"'myabspath.h'\" unpacked with wrong size!
- fi
- # end of 'myabspath.h'
- fi
- if test -f 'rk_button.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rk_button.c'\"
- else
- echo shar: Extracting \"'rk_button.c'\" \(7389 characters\)
- sed "s/^X//" >'rk_button.c' <<'END_OF_FILE'
- X#include "rk_button.h"
- X#include "file+rk.h"
- X
- Xextern maxk;
- Xextern max_nodes;
- Xextern max_freq;
- Xint maxprime=16*1024;
- X
- X /** shared with rk_file/file+rk **/
- Xchar first[MAX_SET], /* the first letter of each pred */
- X context[MAX_CMD_LINE_LENGTH] = "\07", /* last chars entered */
- X old_context[MAX_CMD_LINE_LENGTH] = "\07";
- XBuffer Buf, CBuf; /* ptrs into the model k levels */
- Xchar *prime_file; /* file to prime from and log to */
- Xint next_free = 0; /* index of next free node avail */
- Xlong psize; /* # chars to prime from prime_file*/
- X /* zero freqs, maybe overwritten */
- Xstatic char zero_freq[128] = { /* by a user supplied $home/file */
- X '\n', ' ', 'e', 's', 't', 'r', 'a', 'l',
- X 'n', '.', 'c', 'i', 'm', 'o', 'd', 'h',
- X 'p', 'u', 'f', 'b', 'w', 'g', '-', 'y',
- X '/', 'v', 'k', '*', 'x', '5', '1', '2',
- X '4', '>', 'q', '\07', '3', 'z', '0', 'j',
- X 'M', 'I', '6', '\'', 'E', '~', 'A', ',',
- X 'S', 'D', 'R', '?', 'C', '|', 'B', 'T',
- X 'P', 'U', '!', '_', '<', 'N', '8', '@',
- X '&', '7', '\\', '"', 'J', ')', '(', '[',
- X ']', 'F', 'L', ':', 'O', 'K', '9', 'H',
- X '+', '$', 'W', 'Y', '=', 'G', ';', '^',
- X '{', 'X', 'Q', '#', '}', 'V', '%', 'Z',
- X '`', '\b', '\t', '\26', '\00', '\01', '\02', '\03',
- X '\04', '\05', '\06', '\13', '\f', '\r', '\16', '\17',
- X '\20', '\21', '\22', '\23', '\24', '\25', '\27', '\30',
- X '\31', '\32', '\33', '\34', '\35', '\36', '\37','\177',};
- X
- Xchar *zero_freq_file;
- X
- Xstatic char pred_set[MAX_SET]; /* flags chars already in first[]*/
- X
- Xstatic NodePtr free_nodes; /* now use malloc to get at init */
- Xstatic NodePtr root; /* the root of the k model trie */
- X
- XNodePtr create_node() { /* return ptr to a new node or abort */
- X if (next_free >= max_nodes) {
- X char *malloc(); NodePtr nptr;
- X nptr = (NodePtr) malloc((unsigned) sizeof(Node));
- X if (nptr == nil) /* SHOULD FORGET AND CONTINUE ON */
- X abortit ("Out of memory in create_node.\n",-1);
- X next_free++; /* just for show_free_nodes */
- X return(nptr); /* if more are needed */
- X } else return(&free_nodes[next_free++]); /* first nodes upto MAX */
- X}
- X
- XNodePtr move_up(nptr, c) NodePtr nptr; char c; {
- X
- X NodePtr xptr, fxptr, last_ptr, last_fptr; int state;
- X
- X if (nptr == nil) xptr = nil;
- X else {
- X if (nptr->up == nil) state = START;
- X else {
- X fxptr = xptr = nptr->up; last_fptr = last_ptr = nil;
- X state = SCANNING;
- X do {
- X if (xptr == nil) state = END;
- X else {
- X if (fxptr->count > xptr->count) {
- X last_fptr = last_ptr; fxptr = xptr; }
- X if (xptr->value == c) {
- X state = FOUND;
- X if (fxptr != xptr) {
- X if (last_fptr == nil) nptr->up = xptr;
- X else last_fptr->next = xptr;
- X last_ptr->next = xptr->next; xptr->next = fxptr;
- X } } else { last_ptr = xptr; xptr = xptr->next; }
- X } } while (state == SCANNING);
- X }
- X switch (state) {
- X case FOUND:
- X if (++(xptr->count) == max_freq) { /* Forgets on halving 1 */
- X /*last_fptr =*/ fxptr = nptr->up;
- X while (fxptr != nil) { /* JJD 9-86 */
- X fxptr->count++;
- X fxptr->count >>= 1;
- X/* DOESN'T FORGET A NODES SUBTREE NODES YET SO DON'T DO IT */
- X/* MAY HAcE TO INCREASE max_freq TO REDUCE HALcING & OcERHEAD */
- X/* if (fxptr->count == 0) {
- X last_fptr->next = fxptr->next;
- Xwrite(1,"1/2 free\n",9);
- X Free(fxptr);
- X fxptr = last_fptr->next;
- X } else {
- X last_fptr = fxptr; */
- X fxptr = fxptr->next;
- X
- X }
- X }
- X break;
- X case START: case END:
- X xptr = create_node();
- X xptr->value = c; xptr->count = 1;
- X xptr->up = xptr->next = nil;
- X if (state == START) nptr->up = xptr;
- X else last_ptr->next = xptr;
- X break;
- X }}
- X return (xptr);
- X}
- X
- Xfind_first(buf) Buffer buf; { /* find 1st char of all pred in context */
- X
- X int i, order = 0; NodePtr xptr; char *p;
- X
- X for (p= &pred_set[0]; p< &pred_set[MAX_SET]; p++) *p = '\0';
- X for (i=maxk-1; i>=0; i--) {
- X if (buf[i] != nil)
- X if (buf[i]->up != nil) {
- X xptr = buf[i]->up;
- X while (xptr != nil) {
- X if (!pred_set[(int)xptr->value]) {
- X pred_set[(int)xptr->value]++;
- X first[order++] = xptr->value;
- X }
- X xptr = xptr->next;
- X } } }
- X for (p= &zero_freq[0]; p< &zero_freq[MAX_SET]; p++)
- X if (!pred_set[(int)*p]) first[order++] = *p;
- X}
- X
- Xchar first_pred(buf) Buffer buf; {
- X int i = maxk-1;
- X for (;;) {
- X if (buf[i] != nil)
- X if (buf[i]->up != nil) return (buf[i]->up->value);
- X if (i == 0) return((char)1);
- X i--;
- X }
- X}
- X
- XNodePtr scan_up(nptr,c) NodePtr nptr; char c; {
- X
- X NodePtr xptr;
- X if (nptr == nil) return(nil);
- X else {
- X xptr = nptr->up;
- X for (;;) {
- X if (xptr == nil) return (nil);
- X else if (xptr->value == c) return(xptr);
- X else xptr = xptr->next;
- X } }
- X}
- X
- Xinit_reactive() {
- X double atof(), u;
- X register int i; FILE *from, *popen();
- X char c, *b, *rindex(), tbuf[256], home[128];
- X char cbuf[32+1], *cstart, *cend, *end; int full; long size;
- X
- X /* get a bunch of nodes for starters */
- X free_nodes = (NodePtr) malloc((unsigned) (max_nodes * sizeof(Node)));
- X if (free_nodes == nil) {
- X sprintf (tbuf, "cannot allocate %d nodes.\n", max_nodes);
- X abortit (tbuf, -1);
- X }
- X /* set up root and pointers into model */
- X CBuf[0] = Buf[0] = root = create_node();
- X root->up = root->next = nil;
- X root->count = 1;
- X for (i=1; i<=maxk; i++) Buf[i] = nil;
- X if ((from = fopen (zero_freq_file, "r")) != NULL) {
- X i = 0;
- X while (((int)(c = getc(from))) != EOF) {
- X zero_freq[i++] = c;
- X if (((int)(c = getc(from))) == EOF) break; /* del NL */
- X if (i>127) break; /* test if okay */
- X }
- X } /* else use built in zero_freq[] */
- X /* calc amount to prime, sys load dependent*/
- X if ((from = popen ("uptime", "r")) != NULL) {
- X fgets (tbuf, 128, from);
- X b = rindex (tbuf, ':'); b++;
- X u = atof(b);
- X pclose (from);
- X } else u = 1.0;
- X if (u > 1.0) psize = (long) ((double)((double) maxprime) / u);
- X else psize = (long) (maxprime);
- X /* if user has .rk.log_file, prime from it */
- X if ((from = fopen (prime_file, "r")) != NULL) {
- X fseek (from, 0L, 2); /* find out how long it is */
- X size = ftell (from);
- X if (size > psize) { /* prime max chars at end */
- X fseek (from, -psize, 2); /* start after ^G mark */
- X/* on second thought, if not "logged" by rk, may be no ^Gs in the file */
- X/* while ((((int)(c = getc(from))) != EOF) && (c != '\07')) ;*/
- X } else rewind (from);
- X cstart = cend = cbuf; end = &cbuf[maxk]; full = 0;
- X while (((int)(c = getc(from))) != EOF) {
- X *cstart = c;
- X if (full) { ++cstart; if (cstart > end) cstart = cbuf; }
- X if (++cend > end) { cend = cbuf; full = 1; }
- X *cend = '\0';
- X for (i=maxk; i>0; i--) Buf[i] = move_up(Buf[i-1],c);
- X }
- X i = 0; /* align the context */
- X while (cstart != cend) {
- X context[i] = old_context[i] = *cstart++; i++;
- X if (cstart > end) cstart = cbuf;
- X }
- X fclose (from);
- X }
- X}
- X
- END_OF_FILE
- if test 7389 -ne `wc -c <'rk_button.c'`; then
- echo shar: \"'rk_button.c'\" unpacked with wrong size!
- fi
- # end of 'rk_button.c'
- fi
- if test -f 'rk_button.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rk_button.h'\"
- else
- echo shar: Extracting \"'rk_button.h'\" \(987 characters\)
- sed "s/^X//" >'rk_button.h' <<'END_OF_FILE'
- X/* definitions for rk_button, written by John Darragh, Calgary, revised 3-89
- X */
- X#include <ctype.h>
- X#include <stdio.h>
- X
- X#define false 0
- X#define true 1
- X#define nil ((NodePtr)0)
- X#define MAX_SET 128 /* max # of different symbols (ASCII) */
- X#define TOP_K 10
- X
- X#define START 0 /* values for state variables */
- X#define SCANNING 1
- X#define FOUND 2
- X#define END 3
- X
- Xtypedef struct node { /** variable length Markov tree node **/
- X char value; /* ASCII symbol value (to MAX_SET-1) */
- X char count; /* frequency count (to max_freq) */
- X struct node *next; /* alternative predictions at this k */
- X struct node *up; /* next k level up, eg 3 points to 4 */
- X} Node;
- Xtypedef Node *NodePtr; /** a pointer to a tree node **/
- Xtypedef NodePtr Buffer[TOP_K+1]; /* k ptrs into the tree k contexts */
- X
- XNodePtr scan_up(), move_up();
- Xchar first_pred();
- END_OF_FILE
- if test 987 -ne `wc -c <'rk_button.h'`; then
- echo shar: \"'rk_button.h'\" unpacked with wrong size!
- fi
- # end of 'rk_button.h'
- fi
- if test -f 'rk_file.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rk_file.c'\"
- else
- echo shar: Extracting \"'rk_file.c'\" \(3279 characters\)
- sed "s/^X//" >'rk_file.c' <<'END_OF_FILE'
- X/* "FILE's" link to rk_button, written by John Darragh, Calgary, revised 3-89
- X *
- X * these are the main function used by file+rk.c to generate predictions
- X */
- X#include "rk_button.h"
- X#include "file+rk.h"
- X
- Xextern int pred_number; /* Defined in file+rk.c */
- Xextern char nl_truncate_mode,
- X eol_only_mode,
- X eol_longer_mode;
- X show_eol_mode;
- Xextern ED_STRUCT editor_data;
- X
- Xextern char first[MAX_SET], /* Defined in rk_button.c */
- X context[MAX_CMD_LINE_LENGTH],
- X old_context[MAX_CMD_LINE_LENGTH];
- Xextern Buffer Buf, CBuf;
- Xextern char *prime_file;
- Xextern char pred_on_display;
- Xint max_len=8;
- Xint max_eol=30;
- Xint maxk=8;
- Xint max_freq=127;
- Xint max_nodes=256*1024; /* 256K */
- X
- X
- Xstatic char temp[1024]; /* scratch string buf */
- X
- X
- Xmake_a_prediction (s) char *s; { /* sets s to the current prediction */
- X
- X char *a = temp; int length, i;
- X
- X if (eol_only_mode && *(editor_data.dot)) { *s = '\0'; return; }
- X strcpy (temp, context);
- X strcat (temp, editor_data.current_buffer);
- X length = strlen (temp) - strlen (editor_data.dot);
- X temp[length] = '\0';
- X if (length > maxk) a = &temp[length - maxk];
- X
- X if (strcmp (old_context, a)) pred_number = 0;
- X strcpy (old_context, a);
- X
- X for (i=1; i<=maxk; i++) CBuf[i] = nil;
- X while (*a) {
- X for (i=maxk; i>0; i--) CBuf[i] = scan_up(CBuf[i-1],*a);
- X a++;
- X }
- X find_first(CBuf);
- X build_menu(CBuf, s);
- X }
- X
- Xupdate_the_model (s) char *s; { /* adds s into the model & updates log */
- X
- X char *a = s, *c = s; int length, i; FILE *to;
- X
- X if (strlen(s) < maxk) {
- X strcpy (temp, context);
- X strcat (temp, s);
- X length = strlen (temp);
- X if (length > maxk) a = &temp[length - maxk];
- X else a = temp;
- X }
- X strcpy (context, a);
- X while (*c) {
- X for (i=maxk; i>0; i--) Buf[i] = move_up(Buf[i-1],*c);
- X c++;
- X } /* do not save "empty" lines in the log file */
- X /* reopen to append log, otherwise create it */
- X if (s[0] != '\n') { /* now log can be manipulated and still used */
- X if ((to = fopen (prime_file, "a")) == NULL) {
- X sprintf (temp, "cannot reopen or create: %s\n", prime_file);
- X abortit (temp, -1);
- X }
- X fputs (s, to); fflush (to);
- X fclose(to);
- X }
- X}
- X
- Xbuild_menu(buf,s) Buffer buf; char *s; { /* fill out prediction in s */
- X
- X int i,j,length; Buffer tbuf; char *bptr = s, c;
- X
- X if (eol_longer_mode && !(*(editor_data.dot))) {
- X length = max_eol
- X - get_display_length(editor_data.current_buffer);
- X if (length < max_len) length = max_len;
- X } else length = max_len;
- X
- X c = first[pred_number];
- X for (i=0; i<=maxk; i++) tbuf[i] = buf[i];
- X for (i=1; i<=length; i++) {
- X if (show_eol_mode)
- X *bptr++ = c;
- X else if((c != '\n') || (i==1))
- X *bptr++ = c;
- X if (nl_truncate_mode && (c == '\n')) goto bp;
- X for (j=maxk; j>=1; j--) tbuf[j] = scan_up (tbuf[j-1],c);
- X c = first_pred(tbuf);
- X }
- Xbp: *bptr = '\0';
- X}
- X
- X
- Xshutdown_() {
- X FILE *to;
- X if ((to = fopen (prime_file, "a")) != NULL) {
- X fputs ("\07", to); fflush (to); fclose(to);
- X }
- X}
- X
- Xabortit (message, status)
- Xchar *message;
- Xint status;
- X{
- X if(pred_on_display)
- X erase_pred_buffer(&editor_data);
- X shutdown_pty_and_tty();
- X shutdown_();
- X fprintf (stderr, "%s", message);
- X fflush (stdout); fflush (stderr);
- X exit (status);
- X}
- END_OF_FILE
- if test 3279 -ne `wc -c <'rk_file.c'`; then
- echo shar: \"'rk_file.c'\" unpacked with wrong size!
- fi
- # end of 'rk_file.c'
- fi
- echo shar: End of archive 1 \(of 4\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-